#ifndef HBASE_CLIENT_H
#define HBASE_CLIENT_H

#include <arpa/inet.h>
#include <protocol/TBinaryProtocol.h>
#include <transport/TSocket.h>
#include <transport/TBufferTransports.h>

#include "Hbase.h"
#include "Hbase_types.h"

using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::hadoop;

using namespace boost;

#define ERROR_PTR(ptr) \
	((unsigned long)(ptr) < 100)
#define UINT(a) \
	((unsigned long)((a) > 0 ? (a) : (-(a))))
#define INT(a) \
	(-((long)(a)))

struct ColumnValue {
	hbase::thrift::Text column;
	hbase::thrift::Text value;
	int64_t timestamp;
	ColumnValue *next;

	ColumnValue();
	~ColumnValue();
};

struct RowResult {
	hbase::thrift::Text table;
	hbase::thrift::Text row;
	ColumnValue *cv;
	ColumnValue *index;
	RowResult *next;

	RowResult();
	~RowResult();
	void free(); //must call manuely
	int insert(ColumnValue &cv);
	int insert(ColumnValue *_cv);
	int insert(hbase::thrift::Text c, hbase::thrift::Text v, int64_t t);
	ColumnValue *nextcolumn();
	void rotate();
};

class HbaseOp
{
public:
	HbaseOp(char *_sv_ip, unsigned short _sv_port);
	~HbaseOp();

	int create(const char *tname, struct ColumnValue *cfamily, int compression = 0);
	RowResult *get(const char *tname);
	//vector<hbase::thrift::TRowResult> get(hbase::thrift::Text &tname, hbase::thrift::Text &row);
	//vector<hbase::thrift::TCell> get(hbase::thrift::Text &tname, hbase::thrift::Text &row, hbase::thrift::Text &col);
	//RowResult *get(hbase::thrift::Text &tname, hbase::thrift::Text &row);
	RowResult *get(const char *tname, const char *row);
	//RowResult *get(hbase::thrift::Text &tname, hbase::thrift::Text &row, hbase::thrift::Text &col);
	RowResult *get(const char *tname, const char *row, const char *col);
	//RowResult *get(const hbase::thrift::Text &tableName, const hbase::thrift::Text &row, const vector<hbase::thrift::Text> &columns);
	RowResult *get(const char *tname, const char *row, struct ColumnValue *columns);
	int put(const char *tname, const char *row, struct RowResult *rowvalue);
	int put(const char *tname, struct RowResult *rows);
	int del(const char *tname, const char *row, struct ColumnValue *rowvalue);
	int del(const char *tname, const char *row);
    int delete_table(const char *tname);
	RowResult *scan(const int32_t nrows);
	int scanopen(const char *tname, const char *startrow, struct ColumnValue *colfamily);
	int scanOpenWithPrefix(const char *tname, const char *startrow, struct ColumnValue *colfamily);
	int scanclose();
	int close();
	int open();
public:
	char sv_ip[INET_ADDRSTRLEN];
	unsigned short sv_port;
	hbase::thrift::HbaseClient *hclient;
    shared_ptr<TTransport> socket;
    shared_ptr<TTransport> transport;
    shared_ptr<TProtocol> protocol;
	hbase::thrift::ScannerID scanid;
	int errnum;
};

void free_rows(RowResult *rows);

#endif
